from hosts import hosts
from vms import vms

class sortRset:
    def __init__(self):
        self.rset = set([])
        self.value = 0.0

def comp(x, y):
    if x.value < y.value:
        return 1
    if x.value == y.value:
        return 0
    return -1

class allocator:
    def __init__(self):
        self.hosts = hosts()
        self.vms = vms()
        self.s2v = {}
    def load(self, hf, tf, vf):
        self.vms.load(vf)
        self.hosts.load(hf, tf)
        self.hosts.cluster()
    def cluster_and_cut(self, vmlist, hostlist, k):
        #print
        n = len(vmlist)
        rset = self.hosts.partialCluster(k, hostlist)
        rsortlist = []
        for ri in rset:
            rsorti = sortRset()
            rsorti.rset = ri
            for ni in ri:
                if self.hosts.matrix.has_key(ni):
                    for key, value in self.hosts.matrix[ni].items():
                        if not(key in ri):
                            rsorti.value = rsorti.value + value
                        else:
                            rsorti.value = rsorti.value + value / 2
            rsortlist.append(rsorti)
        rsortlist.sort(comp)
        bsize = []
        #print 'hosts: ',
        for element in rsortlist:
            #print element.rset,
            bsize.append(len(element.rset))
        #print
        s = self.vms.vm_mincut(vmlist, bsize)
        #print 'vms: ', s
#        i = 0
#        for element in rsortlist:
#            print element.rset,
#            print '-----',
#            print list(s)[i]
#            i = i + 1
        i = 0
        for si in s:
            if len(si) == 1:
                self.hosts.place(list(si)[0], list(rsortlist[i].rset)[0])
            i = i + 1
        #print s
        for i in range(k):
            if len(s[i]) > 1:
                self.cluster_and_cut(list(s[i]), list(rsortlist[i].rset), k)
    def outputvm(self):
        for key, value in self.hosts.v2h.items():
            print str(key) + ':' + str(value) + '  ',
        print
    def test(self):
        #print 'Test obj function:',
        sum = 0
        dsum = 0
        for ivm in self.vms.vms:
            if self.vms.matrix.has_key(ivm):
                for jvm in self.vms.matrix[ivm]:
                    dist = self.hosts.distance(ivm, jvm)
                    sum = sum + self.vms.matrix[ivm][jvm] * dist
                    dsum = dsum + self.vms.matrix[ivm][jvm]
        print sum
        return sum
#aloc = allocator()
#aloc.load('../host.in', '../topo.in', '../vm.in')
#k = 4
#aloc.cluster_and_cut(aloc.vms.vms, aloc.hosts.nodes, k)
#print aloc.hosts.v2h
#aloc.test()